package com.yingran.common.util;

import android.text.TextUtils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;

/**
 * Created by Ksy
 */
public final class DateUtil {
    /* *
     *                                        HH:mm    15:44
     *                                       h:mm a    3:44 下午
     *                                      HH:mm z    15:44 CST
     *                                      HH:mm Z    15:44 +0800
     *                                   HH:mm zzzz    15:44 中国标准时间
     *                                     HH:mm:ss    15:44:40
     *                                   yyyy-MM-dd    2016-08-12
     *                             yyyy-MM-dd HH:mm    2016-08-12 15:44
     *                          yyyy-MM-dd HH:mm:ss    2016-08-12 15:44:40
     *                     yyyy-MM-dd HH:mm:ss zzzz    2016-08-12 15:44:40 中国标准时间
     *                EEEE yyyy-MM-dd HH:mm:ss zzzz    星期五 2016-08-12 15:44:40 中国标准时间
     *                     yyyy-MM-dd HH:mm:ss.SSSZ    2016-08-12 15:44:40.461+0800
     *                   yyyy-MM-dd'T'HH:mm:ss.SSSZ    2016-08-12T15:44:40.461+0800
     *                 yyyy.MM.dd G 'at' HH:mm:ss z    2016.08.12 公元 at 15:44:40 CST
     *                                       K:mm a    3:44 下午
     *                             EEE, MMM d, ''yy    星期五, 八月 12, '16
     *                        hh 'o''clock' a, zzzz    03 o'clock 下午, 中国标准时间
     *                 yyyyy.MMMMM.dd GGG hh:mm aaa    02016.八月.12 公元 03:44 下午
     *                   EEE, d MMM yyyy HH:mm:ss Z    星期五, 12 八月 2016 15:44:40 +0800
     *                                yyMMddHHmmssZ    160812154440+0800
     *                   yyyy-MM-dd'T'HH:mm:ss.SSSZ    2016-08-12T15:44:40.461+0800
     * 'DATE('yyyy-MM-dd')' 'TIME('HH:mm:ss')' zzzz    DATE(2016-08-12) TIME(15:44:40) 中国标准时间
     * */

    public static final SimpleDateFormat Format_yyyyMMddHHmmss = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    public static final SimpleDateFormat Format_yyyyMMddHHmm = new SimpleDateFormat("yyyy-MM-dd HH:mm");
    public static final SimpleDateFormat Format_yyyyMMdd = new SimpleDateFormat("yyyy-MM-dd");
    public static final SimpleDateFormat Format_yyyyMMdd_Text = new SimpleDateFormat("yyyy年MM月dd日");
    public static final SimpleDateFormat Format_yyyyMMdd2 = new SimpleDateFormat("yyyy/MM/dd");
    public static final SimpleDateFormat Format_yyyyMM_Text = new SimpleDateFormat("yyyy年MM月");
    public static final SimpleDateFormat Format_MMdd = new SimpleDateFormat("MM-dd");
    public static final SimpleDateFormat Format_yyyyMM = new SimpleDateFormat("yyyy-MM");
    public static final SimpleDateFormat Format_HHmmss = new SimpleDateFormat("HH:mm:ss");
    public static final SimpleDateFormat Format_HHmm = new SimpleDateFormat("HH:mm");

    public static String format2(long time, SimpleDateFormat format) {
        Date parseDate = new Date(time);
        return format.format(parseDate);
    }

    public static String format2(String dateString, SimpleDateFormat format) {
        if (TextUtils.isEmpty(dateString)) {
            return "";
        }
        String parseDateString = null;
        Date parseDate = format2(dateString);
        if (parseDate != null) {
            long time = parseDate.getTime();
            parseDateString = format.format(new Date(time));
        }
        if (TextUtils.isEmpty(parseDateString)) {
            parseDateString = format.format(new Date());
        }
        return parseDateString;
    }

    public static Date format2(String dateString) {
        Date parseDate = null;
        if (TextUtils.isEmpty(dateString)) {
            return new Date();
        }
        try {
            parseDate = Format_yyyyMMddHHmmss.parse(dateString);
        } catch (ParseException e) {
            e.printStackTrace();
            try {
                parseDate = Format_yyyyMMddHHmm.parse(dateString);
            } catch (ParseException e1) {
                e1.printStackTrace();
                try {
                    parseDate = Format_yyyyMMdd.parse(dateString);
                } catch (ParseException e2) {
                    e2.printStackTrace();
                    try {
                        parseDate = Format_yyyyMM.parse(dateString);
                    } catch (ParseException e3) {
                        e3.printStackTrace();
                        try {
                            parseDate = Format_MMdd.parse(dateString);
                        } catch (ParseException e4) {
                            e4.printStackTrace();
                            try {
                                parseDate = Format_HHmm.parse(dateString);
                            } catch (ParseException e5) {
                                e5.printStackTrace();
                            }
                        }
                    }
                }
            }
        }
        if (parseDate == null) {
            parseDate = new Date();
        }
        return parseDate;
    }

    public static ParamsUtil.ParamsTwo<String, String> getCurrentYMDRange() {
        return ParamsUtil.getInstance().create(getMonthStartDay(getYear(), getMonth()), getMonthEndDay(getYear(), getMonth()));
    }

    public static ParamsUtil.ParamsTwo<String, String> getMonthYMDRange(int year, int month) {
        return ParamsUtil.getInstance().create(getMonthStartDay(year, month), getMonthEndDay(year, month));
    }

    public static int getMonth() {
        Calendar c = Calendar.getInstance();
        int month = c.get(Calendar.MONTH);
        return month + 1;
    }

    public static int getMonth(String dateString) {
        Date date = format2(dateString);
        if (date == null) {
            return 0;
        }
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        int month = c.get(Calendar.MONTH);
        return month + 1;
    }

    public static int getMonth(long dateMills) {
        Date date = new Date(dateMills);
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        int month = c.get(Calendar.MONTH);
        return month + 1;
    }

    public static int getCurrentDayIndex() {
        Calendar c = Calendar.getInstance();
        int day = c.get(Calendar.DAY_OF_MONTH);
        return day;
    }

    public static int getYear() {
        Calendar c = Calendar.getInstance();
        int year = c.get(Calendar.YEAR);
        return year;
    }

    public static int getYear(String dateString) {
        Date date = format2(dateString);
        if (date == null) {
            return 0;
        }
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        return c.get(Calendar.YEAR);
    }

    public static int getYear(long dateMills) {
        Date date = new Date(dateMills);
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        return c.get(Calendar.YEAR);
    }

    public static String getMonthStartDay(int year, int month) {
        Calendar c = Calendar.getInstance();
        c.set(Calendar.YEAR, year);
        c.set(Calendar.MONTH, month - 1);
        c.set(Calendar.DAY_OF_MONTH, c.getActualMinimum(Calendar.DAY_OF_MONTH));
        return Format_yyyyMMdd.format(c.getTime());
    }

    public static String getMonthEndDay(int year, int month) {
        Calendar c = Calendar.getInstance();
        c.set(Calendar.YEAR, year);
        c.set(Calendar.MONTH, month - 1);
        c.set(Calendar.DAY_OF_MONTH, c.getActualMaximum(Calendar.DAY_OF_MONTH));
        return Format_yyyyMMdd.format(c.getTime());
    }

    public static int getDaySum(int year, int month) {
        Calendar c = Calendar.getInstance();
        c.set(Calendar.YEAR, year);
        c.set(Calendar.MONTH, month - 1);
        c.set(Calendar.DAY_OF_MONTH, c.getActualMaximum(Calendar.DAY_OF_MONTH));
        return c.get(Calendar.DAY_OF_MONTH);
    }


    public static String getCurrentDate(SimpleDateFormat format) {
        Calendar c = Calendar.getInstance();
        return format.format(c.getTimeInMillis());
    }

    public static String getCurrentDate() {
        return getCurrentDate(Format_yyyyMMdd);
    }

    public static int getDay(String dateString) {
        Date date = format2(dateString);
        if (date == null) {
            return 0;
        }
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        return c.get(Calendar.DAY_OF_MONTH);
    }

    public static int getDay(long dateMills) {
        Date date = new Date(dateMills);
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        return c.get(Calendar.DAY_OF_MONTH);
    }

    public static int getDay() {
        Calendar c = Calendar.getInstance();
        return c.get(Calendar.DAY_OF_MONTH);
    }


    public static String getWeek(String dateString) {
        Date date = format2(dateString);
        if (date == null) {
            return "**";
        }
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        int i = c.get(Calendar.DAY_OF_WEEK);
        if (i == 1) {
            return "周日";
        } else if (i == 2) {
            return "周一";
        } else if (i == 3) {
            return "周二";
        } else if (i == 4) {
            return "周三";
        } else if (i == 5) {
            return "周四";
        } else if (i == 6) {
            return "周五";
        } else if (i == 7) {
            return "周六";
        }
        return "**";
    }

    public static long getCurrentTimeInMillis() {
        Calendar c = Calendar.getInstance();
        return c.getTimeInMillis();
    }

    private static final int[] STARS_FLAGS = {20, 19, 21, 21, 21, 22, 23, 23, 23, 24, 23, 22};
    private static final String[] STARS = {
            "水瓶座", "双鱼座", "白羊座", "金牛座", "双子座", "巨蟹座",
            "狮子座", "处女座", "天秤座", "天蝎座", "射手座", "魔羯座"
    };

    public static String getStar(final int month, final int day) {
        return STARS[day >= STARS_FLAGS[month - 1]
                ? month - 1
                : (month + 10) % 12];
    }

    public static String getSmartDate(long millis) {
        if (millis <= 0) {
            return "";
        }
        long now = System.currentTimeMillis();
        long span = now - millis;
        if (span < 0) {
            return String.format("%tF", millis);
        }
        if (span < 1000) {
            return "刚刚";
        } else if (span < 60 * 1000) {
            return String.format(Locale.getDefault(), "%d秒前", span / 1000);
        } else if (span < 60 * 60 * 1000) {
            return String.format(Locale.getDefault(), "%d分钟前", span / (60 * 1000));
        }
        // 获取当天 00:00
        long startOfToday = getStartOfToday();
        if (millis >= startOfToday) {
            return String.format("今天%tR", millis);
        } else if (millis >= startOfToday - 24 * 60 * 60 * 1000) {
            return String.format("昨天%tR", millis);
        } else {
            return String.format("%tF", millis);
        }
    }

    private static long getStartOfToday() {
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.MILLISECOND, 0);
        return cal.getTimeInMillis();
    }


    public static long getTimesMillis(String dateString) {
        Date date = format2(dateString);
        return date.getTime();
    }



    /**
     * 将Date转为时间描述
     */
    public static String getTimeDescribe(long messageTime) {
        String format;
        if (isSameDay(messageTime)) {
            format = "HH:mm";
        } else if (isYesterday(messageTime)) {
            format = "昨天 HH:mm";
        } else {
            format = "MM-dd HH:mm";
        }
        return new SimpleDateFormat(format, Locale.US).format(new Date(messageTime));
    }

    /**
     * 判断时间是否在今天
     *
     * @param inputTime
     * @return
     */
    public static boolean isSameDay(long inputTime) {
        ParamsUtil.ParamsTwo<Long, Long> tStartAndEndTime = getTodayStartAndEndTime();
        if (inputTime > tStartAndEndTime.first && inputTime < tStartAndEndTime.second)
            return true;
        return false;
    }

    /**
     * 判断时间是否在昨天
     *
     * @param inputTime
     * @return
     */
    public static boolean isYesterday(long inputTime) {
        ParamsUtil.ParamsTwo<Long, Long> yStartAndEndTime = getYesterdayStartAndEndTime();
        if (inputTime > yStartAndEndTime.first && inputTime < yStartAndEndTime.second)
            return true;
        return false;
    }

    /**
     * 获取今天时间的始点和终点
     *
     * @return
     */
    public static ParamsUtil.ParamsTwo<Long, Long> getTodayStartAndEndTime() {
        Calendar calendar1 = Calendar.getInstance();
        calendar1.set(Calendar.HOUR_OF_DAY, 0);
        calendar1.set(Calendar.MINUTE, 0);
        calendar1.set(Calendar.SECOND, 0);
        calendar1.set(Calendar.MILLISECOND, 0);
        Date startDate = calendar1.getTime();
        long startTime = startDate.getTime();

        Calendar calendar2 = Calendar.getInstance();
        calendar2.set(Calendar.HOUR_OF_DAY, 23);
        calendar2.set(Calendar.MINUTE, 59);
        calendar2.set(Calendar.SECOND, 59);
        calendar2.set(Calendar.MILLISECOND, 999);
        Date endDate = calendar2.getTime();
        long endTime = endDate.getTime();
        ParamsUtil.ParamsTwo<Long, Long> longLongParamsTwo = ParamsUtil.getInstance().create(startTime, endTime);
        return longLongParamsTwo;
    }

    /**
     * 获取昨天时间的始点和终点
     *
     * @return
     */
    public static ParamsUtil.ParamsTwo<Long, Long> getYesterdayStartAndEndTime() {
        Calendar calendar1 = Calendar.getInstance();
        calendar1.add(Calendar.DATE, -1);
        calendar1.set(Calendar.HOUR_OF_DAY, 0);
        calendar1.set(Calendar.MINUTE, 0);
        calendar1.set(Calendar.SECOND, 0);
        calendar1.set(Calendar.MILLISECOND, 0);

        Date startDate = calendar1.getTime();
        long startTime = startDate.getTime();

        Calendar calendar2 = Calendar.getInstance();
        calendar2.add(Calendar.DATE, -1);
        calendar2.set(Calendar.HOUR_OF_DAY, 23);
        calendar2.set(Calendar.MINUTE, 59);
        calendar2.set(Calendar.SECOND, 59);
        calendar2.set(Calendar.MILLISECOND, 999);
        Date endDate = calendar2.getTime();
        long endTime = endDate.getTime();
        ParamsUtil.ParamsTwo<Long, Long> longLongParamsTwo = ParamsUtil.getInstance().create(startTime, endTime);
        return longLongParamsTwo;
    }

    public static String convertSecondsToTime(long seconds) {
        String timeStr = null;
        int hour = 0;
        int minute = 0;
        int second = 0;
        if (seconds <= 0)
            return "00:00";
        else {
            minute = (int) seconds / 60;
            if (minute < 60) {
                second = (int) seconds % 60;
                timeStr = unitFormat(minute) + ":" + unitFormat(second);
            } else {
                hour = minute / 60;
                if (hour > 99)
                    return "99:59:59";
                minute = minute % 60;
                second = (int) (seconds - hour * 3600 - minute * 60);
                timeStr = unitFormat(hour) + ":" + unitFormat(minute) + ":" + unitFormat(second);
            }
        }
        return timeStr;
    }

    public static String convertSecondsToFormat(long seconds, String format) {

        if (TextUtils.isEmpty(format))
            return "";

        Date date = new Date(seconds);
        SimpleDateFormat sdf = new SimpleDateFormat(format, Locale.getDefault());
        return sdf.format(date);
    }

    private static String unitFormat(int i) {
        String retStr = null;
        if (i >= 0 && i < 10)
            retStr = "0" + Integer.toString(i);
        else
            retStr = "" + i;
        return retStr;
    }
}
